package com.ziq.base.view.recycleview

import androidx.recyclerview.widget.*
import androidx.viewbinding.ViewBinding
import com.ziq.base.extension.BindingViewHolder


abstract class BaseListAdapter<T : BaseListAdapter.BaseListAdapterData, VB : ViewBinding> : RecyclerView.Adapter<BindingViewHolder<VB>>(), AsyncListDiffer.ListListener<T> {

    private val diffCallback = object : DiffUtil.ItemCallback<T>(){

        override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
            return this@BaseListAdapter.areItemsTheSame(oldItem, newItem)
        }

        override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
            val result = this@BaseListAdapter.areContentsTheSame(oldItem, newItem) && !newItem.hasContentChanged()
            newItem.resetContentChanged()
            return result
        }
    }

    var mDiffer: AsyncListDiffer<T> = AsyncListDiffer<T>(
        AdapterListUpdateCallback(this),
        AsyncDifferConfig.Builder<T>(diffCallback).build()
    )

    init {
        mDiffer.addListListener(this)
    }

    abstract fun areItemsTheSame(oldItem: T, newItem: T): Boolean

    abstract fun areContentsTheSame(oldItem: T, newItem: T): Boolean

    override fun onCurrentListChanged(previousList: MutableList<T>, currentList: MutableList<T>) {
    }

    fun submitList(list: List<T>?) {
        mDiffer.submitList(list)
    }

    fun submitList(list: List<T>?, commitCallback: Runnable?) {
        mDiffer.submitList(list, commitCallback)
    }

    protected open fun getItem(position: Int): T {
        return mDiffer.currentList[position]
    }

    override fun getItemCount(): Int {
        return mDiffer.currentList.size
    }

    fun getCurrentList(): List<T> {
        return mDiffer.currentList
    }


    interface BaseListAdapterData {
        fun hasContentChanged() : Boolean
        fun resetContentChanged()
    }

}